"""
异步辅助工具
用于将同步阻塞操作包装为异步非阻塞
"""
import asyncio
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeoutError
from functools import wraps
from typing import Callable, Any, Optional

# 创建线程池执行器（用于CPU密集或阻塞IO操作）
_executor = ThreadPoolExecutor(max_workers=20, thread_name_prefix="async_helper")


async def run_in_executor(
    func: Callable,
    *args,
    timeout: Optional[float] = 10.0,
    **kwargs
) -> Any:
    """
    在线程池中执行同步函数，避免阻塞事件循环，支持超时控制
    
    Args:
        func: 要执行的同步函数
        *args: 位置参数
        timeout: 超时时间（秒），默认10秒，None表示不限制
        **kwargs: 关键字参数
    
    Returns:
        函数执行结果
        
    Raises:
        asyncio.TimeoutError: 操作超时
    """
    loop = asyncio.get_event_loop()
    
    if kwargs:
        # 如果有关键字参数，使用lambda包装
        task = loop.run_in_executor(_executor, lambda: func(*args, **kwargs))
    else:
        # 只有位置参数时直接传递
        task = loop.run_in_executor(_executor, func, *args)
    
    # 应用超时控制
    if timeout is not None:
        return await asyncio.wait_for(task, timeout=timeout)
    else:
        return await task


def async_wrap(func: Callable) -> Callable:
    """
    装饰器：将同步函数包装为异步函数
    
    Usage:
        @async_wrap
        def blocking_function():
            # 阻塞操作
            pass
        
        # 现在可以 await blocking_function()
    """
    @wraps(func)
    async def wrapper(*args, **kwargs):
        return await run_in_executor(func, *args, **kwargs)
    return wrapper